#include "moveableframelesswindow.h"


#include <QKeyEvent>
#include <QMouseEvent>
#include <QRect>
#include <QPoint>
#include <QGridLayout>

#include "../wsim_client.h"
#include <jsoncpp/json/json.h> /*jsoncpp -ljsoncpp*/
#include <iostream>
#include <QMessageBox>
#include <QMetaType>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include <QDir>
#include "./transferform.h"

MoveableFramelessWindow::MoveableFramelessWindow(QWidget *parent) :
    QWidget(parent),
    isMove(false)
{
    //设置窗体为无边框
    this->setWindowFlags(Qt::FramelessWindowHint);

    //设置底层背景透明
    setAttribute(Qt::WA_TranslucentBackground);


    qRegisterMetaType<clientItem>("clientItem");
    qRegisterMetaType<WS_MESSAGE>("WS_MESSAGE");
    qRegisterMetaType<wsimBIN_head>("wsimBIN_head");
    qRegisterMetaType<linkItem>("linkItem");
    connect(this, SIGNAL(sigAddClient(clientItem,int)), this, SLOT(slotAddClient(clientItem,int)));  //将自定义槽连接到自定义信号
    connect(this,SIGNAL(sigDropClient(clientItem)),this,SLOT(slotDropClient(clientItem)));
    connect(this,SIGNAL(sigMessage(WS_MESSAGE)),this,SLOT(slotMessage(WS_MESSAGE)));
    connect(this,SIGNAL(sig_wsFile(wsimBIN_head)),this,SLOT(slot_wsFile(wsimBIN_head)));
    connect(this,SIGNAL(sig_wsRequest(int,int,QString,linkItem)),this,SLOT(slot_wsRequest(int,int,QString,linkItem)));
    connect(this,SIGNAL(sig_wsTransfer(int,int,int,int)),this,SLOT(slot_wsTransfer(int,int,int,int)));
    connect(this,SIGNAL(sig_wsTeamTransfer(int,int,int,int,QByteArray)),this,SLOT(slot_wsTeamTransfer(int,int,int,int,QByteArray)));
    connect(this,SIGNAL(sig_wsTeamClose(int,int,int)),this,SLOT(slot_wsTeamClose(int,int,int)));
    connect(this,SIGNAL(sig_wsTeamCommand(int,int,int,QString)),this,SLOT(slot_wsTeamCommand(int,int,int,QString)));
}

void MoveableFramelessWindow::mousePressEvent(QMouseEvent *event)
{
    //判断位置
    bool shouldMove=isPointInDragnWidget(getDragnWidget(),event->pos());

    if(shouldMove){
          pressedPoint=event->pos();
          isMove=true;
    }

    event->ignore();

}

void MoveableFramelessWindow::mouseMoveEvent(QMouseEvent *event)
{
    if((event->buttons()==Qt::LeftButton) && isMove==true){

            QPoint currPoint=this->pos();
            currPoint.setX(currPoint.x()+event->x()-pressedPoint.x());
            currPoint.setY(currPoint.y()+event->y()-pressedPoint.y());
            this->move(currPoint);
     }
}

void MoveableFramelessWindow::mouseReleaseEvent(QMouseEvent *event)
{
    isMove=false;

}

bool MoveableFramelessWindow::isPointInDragnWidget(const QWidget *widget, const QPoint &point)
{
    //判断位置
    QRect rect=widget->rect();

    bool isIn=point.x()>=rect.left()&&point.x()<=rect.right()&&point.y()>=rect.top()&&point.y()<=rect.bottom();

    return isIn;
}
/******************************************
 * 自定义事件
 * *************************************/
bool MoveableFramelessWindow::event(QEvent *e)
{
    if(e->type() == WSIM_Event::m_WS_event){
            WSIM_Event* pData=(WSIM_Event*)e;
            //QMessageBox::warning(this, tr("event"), QString::fromStdString(pData->buf), QMessageBox::Yes);
            callBack(pData->fd,pData->datatype,pData->buf,pData->bufLen);
            return true;

        }else if(e->type() == WSIM_Event::m_WS_close){

            onCloseWS();
            return true;

        }

        return QWidget::event(e);
}

/***********************************************************
 * 消息事件处理函数
 * **********************************************************/
int MoveableFramelessWindow::callBack(int fd, WebsocketData_Type datatype, char *buf, unsigned int bufLen)
{
    //重要第一步
    char* tmpbuf;
    if(bufLen>0)
    {
        tmpbuf=(char*)calloc(bufLen,sizeof(char));
        memcpy(tmpbuf,buf,bufLen);

        if(buf) free(buf);
    }
    if(datatype==WDT_BINDATA){
        if(bufLen>0){

         wsimBIN_head *pHead=(wsimBIN_head*)tmpbuf;

         int i=WSIM_client::findLinkUp(0,pHead->fromfd,pHead->magic);
            if(i>=0){
        if(pHead->binType==BINTYPE_FILE){
        QString filename=QString("%1_%2").arg(pHead->magic).arg(pHead->label);//.arg(pHead->index);

            QString m_fileName=QString("%1/%2").arg(QDir::homePath()).arg(filename);
           QFile* m_localFile = new QFile(m_fileName);
                        if (!m_localFile->open(QIODevice::WriteOnly|QIODevice::Append)){
                            qDebug() << "WDT_BINDATA: open file error!";
                        }
                        else{

                           if((bufLen-sizeof(wsimBIN_head))>0){
                                const char *databuf=(const char *)(tmpbuf+sizeof(wsimBIN_head));
                                m_localFile->write(databuf,pHead->dataLen);
                                //if(pHead->dataLen<m_linkList.at(i).maxPageLen);

                            }

                        }

                            m_localFile->close();               

        }
        else if(pHead->binType==BINTYPE_TEAMVIEW){
            if((pHead->index==0)&&(pHead->dataLen==0))
                emit sig_wsTeamClose(0,pHead->fromfd,pHead->magic);
            else{                
                const char *databuf=(const char *)(tmpbuf+sizeof(wsimBIN_head));
                QByteArray barray;
                barray=QByteArray(databuf,pHead->dataLen);
                emit sig_wsTeamTransfer(0,pHead->fromfd,pHead->magic,pHead->index,barray   );
            }
        }
            emit sig_wsTransfer(0,pHead->fromfd,pHead->magic,pHead->index);
            }
        //qDebug()<<bufLen;
        }
    }
    else if(datatype==WDT_TXTDATA){
                    Json::Reader reader;
                        Json::Value root;
                        if(reader.parse(tmpbuf,root))//reader将字符串解析到root
                        {
                            if(root["stype"].isNull())
                            {
                                std::cout<<"无法解析数据！！！"<<std::endl;
                                //pthread_exit((void*)pthread_self()) ;
                                goto end;
                            }
                                std::string stype=root["stype"].asString();//访问节点
                                if(stype.compare("Hi~") == 0)
                                {
                                    server_fd=root["fd"].asInt();
                                    server_uuid=root["uuid"].asString();
                                    std::string reStr=root["message"].asString();
                                    std::cout<<std::endl<<reStr<<std::endl;
                 }

                 else if(stype.compare("newjoin")==0)
                {
                    int join_size=root["arrayUser"].size();
                    for(int i=0;i<join_size;++i)
                    {
                        int nfd=root["arrayUser"][i]["fd"].asInt();
                        std::string nNickname=root["arrayUser"][i]["nickname"].asString();
                        std::string nUUID=root["arrayUser"][i]["uuid"].asString();
                        std::string nMood=root["arrayUser"][i]["mood"].asString();
                        std::string nOrgan=root["arrayUser"][i]["organ"].asString();
                        std::string nGroup=root["arrayUser"][i]["group"].asString();
                        bool nBreg=false;
                        if(root["arrayUser"][i]["breg"]!=Json::nullValue)
                            nBreg=root["arrayUser"][i]["breg"].asBool();
                        // cout<<endl<<"客户上线："<<nNickname<<"["<<nfd<<":"<<nUUID<<"] 。"<<endl;
                        if(nfd==server_fd) continue;
                        clientItem item;
                        item.fd=nfd;
                        item.nickname=QString::fromStdString(nNickname);
                        item.uuid=QString::fromStdString(nUUID);
                        item.mood=QString::fromStdString(nMood);
                        item.group=QString::fromStdString(nGroup);
                        item.organ=QString::fromStdString(nOrgan);
                        item.breg=nBreg;
                        emit sigAddClient(item,0);//发信号

                    }
                }
                                else if(stype.compare("dropline")==0)
                                {
                                        int join_size=root["arrayUser"].size();
                                        for(int i=0;i<join_size;++i)
                                        {
                            int nfd=root["arrayUser"][i]["fd"].asInt();
                            std::string nNickname=root["arrayUser"][i]["nickname"].asString();
                            std::string nUUID=root["arrayUser"][i]["uuid"].asString();
                                                //cout<<endl<<"客户下线："<<nNickname<<"["<<nfd<<":"<<nUUID<<"] 。"<<endl;
                            clientItem item;
                            item.fd=nfd;
                            item.nickname=QString::fromStdString(nNickname);
                            item.uuid=QString::fromStdString(nUUID);
                            emit sigDropClient(item);//发信号
                                        }
                                }
                                else if(stype.compare("message")==0)
                                {
                                    std::string fname=root["form"].asString();
                                    std::string fuuid=root["fuuid"].asString();
                                    std::string msg=root["message"].asString();
                                    int ffd=root["ffd"].asInt();

                                    WS_MESSAGE wsmsg;
                                    wsmsg.f_fd=ffd;
                                    wsmsg.f_nickname=QString::fromStdString(fname);
                                    wsmsg.f_uuid=QString::fromStdString(fuuid);
                                    wsmsg.message=QString::fromStdString(msg);
                                    emit sigMessage(wsmsg);
                                }
                                else if(stype.compare("request")==0)
                                {
                                    std::string fname=root["form"].asString();
                                    std::string fuuid=root["fuuid"].asString();
                                    int magic=root["magic"].asInt();
                                    std::string request="来自 "+fname+"。 "+root["request"].asString();
                                    int ffd=root["ffd"].asInt();
                                    std::string label=root["label"].asString();
                                    int maxPageLen=root["maxPageLen"].asInt();
                                    int maxPageNum=root["maxPageNum"].asInt();
                                    linkItem item;
                                    item.ffd=ffd;
                                    item.label=label;
                                    item.magic=magic;
                                    item.binType=root["binType"].asInt();
                                    item.tfd=0;
                                    item.maxPageLen=maxPageLen;
                                    item.maxPageNum=maxPageNum;
                                    item.filename=label;
                                    emit sig_wsRequest(ffd,magic,QString::fromStdString(request),item);

                                }
                                else if(stype.compare("response")==0)
                                {
                                    std::string fname=root["form"].asString();
                                    std::string fuuid=root["fuuid"].asString();
                                    int magic=root["magic"].asInt();
                                    QString msg=QString::fromStdString(root["response"].asString());
                                    int ffd=root["ffd"].asInt();

                                    if(msg.compare("yes")==0)
                                    {
                                        int i=-1;
                                        i=WSIM_client::findLinkUp(ffd,0,magic);
                                        if(i>=0){


                                                    transferForm*t=&(MY_TRANSFER_FORM);
                                                    if(t!=NULL)
                                                        t->beginTransfer(i);

                                        }
                                    }
                                    else
                                    {
                                        WSIM_client::delLinkUp(ffd,0,magic);
                                    }
                                }
                                else if(stype.compare("teamCommand")==0)//协助指令
                                {
                                    std::string fname=root["form"].asString();
                                    std::string fuuid=root["fuuid"].asString();
                                    int magic=root["magic"].asInt();
                                    QString command=QString::fromStdString(root["command"].asString());
                                    int ffd=root["ffd"].asInt();
                                    emit sig_wsTeamCommand(0,ffd,magic,command);

                                }
                                else if(stype.compare("ret")==0)//调用返回
                                {

                                    std::string execName=root["exec"].asString();
                                    std::cout<<"ret"<<execName<<endl;
                                    if(execName.compare("reMood")==0)
                                    {
                                        int join_size=root["arrayRet"].size();
                                        for(int i=0;i<join_size;++i)
                                        {
                                            int nfd=root["arrayRet"][i]["fd"].asInt();
                                            std::string nNickname=root["arrayRet"][i]["nickname"].asString();
                                            std::string nUUID=root["arrayRet"][i]["uuid"].asString();
                                            std::string nMood=root["arrayRet"][i]["mood"].asString();
                                            if(nfd==server_fd) continue;
                                            clientItem item;
                                            item.fd=nfd;
                                            item.nickname=QString::fromStdString(nNickname);
                                            item.uuid=QString::fromStdString(nUUID);
                                            item.mood=QString::fromStdString(nMood);
                                            emit sigAddClient(item,0);//发信号
                                        }
                                    }
                                    else if(execName.compare("join")==0)
                                    {
                                        std::string returnStr=root["return"].asString();
                                        QMessageBox::about(this,"登入",QString::fromStdString(returnStr));
                                    }
                                    else if(execName.compare("readUserInfo")==0)
                                    {
                                        int join_size=root["arrayRet"].size();
                                        if(join_size>0){
                                            /*
                                        Json::Value fields=root["arrayRet"]["fields"];

                                                    for(int f=0;f<fields.size();++f)
                                                    {
                                                        std::cout<<fields[f]["name"].asString()<<"\t";
                                                    }
                                                    std::cout<<endl;*/
                                                    Json::Value rows=root["arrayRet"]["rows"];
                                                    if(rows.size()>0){
                                                    if(rows[0]["nickname"]!=Json::nullValue)
                                                    server_nickname=rows[0]["nickname"].asString();
                                                    if(rows[0]["organ"]!=Json::nullValue)
                                                    server_organ=rows[0]["organ"].asString();
                                                    if(rows[0]["name"]!=Json::nullValue)
                                                    server_name=rows[0]["name"].asString();
                                                    if(rows[0]["mobileNumber"]!=Json::nullValue)
                                                    server_mobileNumber=rows[0]["mobileNumber"].asString();
                                                    if(rows[0]["group"]!=Json::nullValue)
                                                    server_group=rows[0]["group"].asString();
                                                    }
                                                    /*for(int r=0;r<rows.size();++r)
                                                    {
                                                        Json::Value row=rows[r];
                                                        for(int f=0;f<fields.size();++f)
                                                        {
                                                            string name=fields[f]["name"].asString();
                                                            std::cout<<row[name]<<"\t";
                                                        }
                                                        std::cout<<endl;
                                                    }*/
                                        }
                                    }
                                    else if(execName.compare("readClients")==0)
                                    {
                                        int lineClient_size=root["arrayRet"].size();
                                        std::cout<<std::endl<<"在线用户："<<lineClient_size<<"个"<<std::endl;
                                        for(int i=0;i<lineClient_size;++i)
                                        {
                                            int clientfd=root["arrayRet"][i]["fd"].asInt();
                                            std::string clientnickname=root["arrayRet"][i]["nickname"].asString();
                                            std::string cuuid=root["arrayRet"][i]["uuid"].asString();
                                            std::string mood=root["arrayRet"][i]["mood"].asString();
                                            std::string organ=root["arrayRet"][i]["organ"].asString();
                                            std::string group=root["arrayRet"][i]["group"].asString();
                                            bool breg=false;
                                            if(root["arrayRet"][i]["breg"]!=Json::nullValue)
                                                breg=root["arrayRet"][i]["breg"].asBool();
                                            //std::cout<<"\t"<<clientnickname<<"["<<clientfd<<":"<<cuuid<<"]"<<std::endl;
                                            if(clientfd==server_fd) continue;
                                            clientItem item;
                                            item.fd=clientfd;
                                            item.nickname=QString::fromStdString(clientnickname);
                                            item.uuid=QString::fromStdString(cuuid);
                                            item.mood=QString::fromStdString(mood);
                                            item.group=QString::fromStdString(group);
                                            item.organ=QString::fromStdString(organ);
                                            item.breg=breg;
                                            emit sigAddClient(item,0);//发信号
                                            }
                                    }
                                    else if(execName.compare("readNoRegClients")==0)
                                    {
                                        int lineClient_size=root["arrayRet"].size();
                                        std::cout<<std::endl<<"未注册在线用户："<<lineClient_size<<"个"<<std::endl;
                                        for(int i=0;i<lineClient_size;++i)
                                        {
                                            int clientfd=root["arrayRet"][i]["fd"].asInt();
                                            std::string clientnickname=root["arrayRet"][i]["nickname"].asString();
                                            std::string cuuid=root["arrayRet"][i]["uuid"].asString();
                                            std::string mood=root["arrayRet"][i]["mood"].asString();
                                            std::string organ=root["arrayRet"][i]["organ"].asString();
                                            std::string group=root["arrayRet"][i]["group"].asString();
                                            bool breg=false;
                                            if(root["arrayRet"][i]["breg"]!=Json::nullValue)
                                                breg=root["arrayRet"][i]["breg"].asBool();
                                            //std::cout<<"\t"<<clientnickname<<"["<<clientfd<<":"<<cuuid<<"]"<<std::endl;
                                            if(clientfd==server_fd) continue;
                                            clientItem item;
                                            item.fd=clientfd;
                                            item.nickname=QString::fromStdString(clientnickname);
                                            item.uuid=QString::fromStdString(cuuid);
                                            item.mood=QString::fromStdString(mood);
                                            item.group=QString::fromStdString(group);
                                            item.organ=QString::fromStdString(organ);
                                            item.breg=breg;
                                            if(breg);
                                            else
                                            emit sigAddClient(item,1);//发信号
                                            }
                                    }
                                    else if(execName.compare("readRegClients")==0)
                                    {
                                        int lineClient_size=root["arrayRet"].size();
                                        std::cout<<std::endl<<"已注册在线用户："<<lineClient_size<<"个"<<std::endl;
                                        for(int i=0;i<lineClient_size;++i)
                                        {
                                            int clientfd=root["arrayRet"][i]["fd"].asInt();
                                            std::string clientnickname=root["arrayRet"][i]["nickname"].asString();
                                            std::string cuuid=root["arrayRet"][i]["uuid"].asString();
                                            std::string mood=root["arrayRet"][i]["mood"].asString();
                                            std::string organ=root["arrayRet"][i]["organ"].asString();
                                            std::string group=root["arrayRet"][i]["group"].asString();
                                            bool breg=false;
                                            if(root["arrayRet"][i]["breg"]!=Json::nullValue)
                                                breg=root["arrayRet"][i]["breg"].asBool();
                                            if(clientfd==server_fd) continue;
                                            clientItem item;
                                            item.fd=clientfd;
                                            item.nickname=QString::fromStdString(clientnickname);
                                            item.uuid=QString::fromStdString(cuuid);
                                            item.mood=QString::fromStdString(mood);
                                            item.group=QString::fromStdString(group);
                                            item.organ=QString::fromStdString(organ);
                                            item.breg=breg;
                                            if(breg){
                                                if((server_group.compare(group)==0)&&(group.length()>0));//有机构及与当前同一机构的
                                                else
                                                emit sigAddClient(item,2);//发信号
                                            }
                                            }
                                    }
                                    else if(execName.compare("readOrganUser")==0)
                                    {
                                        int lineClient_size=root["arrayRet"].size();
                                        std::cout<<std::endl<<"同机构在线用户："<<lineClient_size<<"个"<<std::endl;
                                        for(int i=0;i<lineClient_size;++i)
                                        {
                                            int clientfd=root["arrayRet"][i]["fd"].asInt();
                                            std::string clientnickname=root["arrayRet"][i]["nickname"].asString();
                                            std::string cuuid=root["arrayRet"][i]["uuid"].asString();
                                            std::string mood=root["arrayRet"][i]["mood"].asString();
                                            std::string organ=root["arrayRet"][i]["organ"].asString();
                                            std::string group=root["arrayRet"][i]["group"].asString();
                                            bool breg=false;
                                            if(root["arrayRet"][i]["breg"]!=Json::nullValue)
                                                breg=root["arrayRet"][i]["breg"].asBool();
                                            if(clientfd==server_fd) continue;
                                            clientItem item;
                                            item.fd=clientfd;
                                            item.nickname=QString::fromStdString(clientnickname);
                                            item.uuid=QString::fromStdString(cuuid);
                                            item.mood=QString::fromStdString(mood);
                                            item.group=QString::fromStdString(group);
                                            item.organ=QString::fromStdString(organ);
                                            item.breg=breg;
                                            if(breg )
                                                if((server_group.compare(group)==0)&&(group.length()>0))//有机构及与当前同一机构的
                                                    emit sigAddClient(item,3);//发信号
                                            }
                                    }
                                    else if(execName.compare("readGroupUser")==0)
                                    {
                                        int lineClient_size=root["arrayRet"].size();
                                        std::cout<<std::endl<<"同兴趣组在线用户："<<lineClient_size<<"个"<<std::endl;
                                        for(int i=0;i<lineClient_size;++i)
                                        {
                                            int clientfd=root["arrayRet"][i]["fd"].asInt();
                                            std::string clientnickname=root["arrayRet"][i]["nickname"].asString();
                                            std::string cuuid=root["arrayRet"][i]["uuid"].asString();
                                            std::string mood=root["arrayRet"][i]["mood"].asString();
                                            std::string organ=root["arrayRet"][i]["organ"].asString();
                                            std::string group=root["arrayRet"][i]["group"].asString();
                                            bool breg=false;
                                            if(root["arrayRet"][i]["breg"]!=Json::nullValue)
                                                breg=root["arrayRet"][i]["breg"].asBool();
                                            if(clientfd==server_fd) continue;
                                            clientItem item;
                                            item.fd=clientfd;
                                            item.nickname=QString::fromStdString(clientnickname);
                                            item.uuid=QString::fromStdString(cuuid);
                                            item.mood=QString::fromStdString(mood);
                                            item.group=QString::fromStdString(group);
                                            item.organ=QString::fromStdString(organ);
                                            item.breg=breg;
                                            //emit sigAddClient(item,3);//发信号
                                            }
                                    }
                                }
                                else
                                    std::cout<<std::endl<<"未处理："<<tmpbuf<<std::endl;
                        }
}
end:
    if(tmpbuf)
        free(tmpbuf);
    return 0;
}


